const name1 = Symbol('name');
const name2 = Symbol('name');


const obj = {
    name: 'bob', // 键值对映射（属性）集合
    1: 0,
    [name1]: 1,
    [name2]: 2,
};

// 映射：Map中每一个键都是唯一的
const map = new Map();
// 可以将任何类型的变量或值作为键名来使用
map.set(obj, '加密的值');

Object.keys(obj); // 4 返回对象所有的键名
map.size; // 可以返回当前Map中键值对（属性）的个数

map.set('key', 'value');
map.get('key'); // 获取以 key 为键（属性）名的（属性）值
map.has('key'); // 判断是否存在 key 这个键值对（属性）
map.delete('key'); // 删除以key为键名的键值对（删除key这个属性）
map.clear(); // 全部清空
map.size; // 当前键值对的数量
map.keys(); // 返回所有的键名的迭代器
map.values(); // 返回所有值的迭代器

map.entries(); // 返回一个迭代器
const iterator = map.entries();
iterator.next(); // 从映射第一个键值对开始，一直到最后一个键值对结束

map.forEach((value, key, mapSelf) => {
    // value 值
    // key 键
    // mapSelf 自己
});


// 集合：Set中的每一个值都是唯一的
const set = new Set();
set.add(1); // 添加一个值
set.add(2);
set.add(3);

set.size; // 3 集合中元素的个数
set.has(1); // 判断是否存在1这个值
set.clear(); // 清空所有的值
set.keys(); // 返回所有值的迭代器 'a'
set.values(); // 返回所有值的迭代器 'a'
set.entries(); // 返回所有值的迭代器 ['a', 'a']
set.delete('a'); // 删除一个元素
set.forEach((value, value2, setSelf) => {
    // value === value2
    console.log(value, value2, setSelf)
});

// 垃圾回收计数器

// 作业：Map Set
// Map
// 1. 频率计数器：给定一个字符串数组，计算每个字符串出现的次数。
// 2. 缓存系统：实现一个简单的LRU（最近最少使用）缓存，支持添加和获取数据，当超过容量时移除最久未使用的数据项。
// 3. 字典映射：创建一个多语言词典，能够根据用户选择的语言来返回相应的翻译。
// 2、3 选一个做即可

/**
 * 1. 定义了一个Counter函数，定义了一个strings字符串数组
 * 2. 定义了一个类型为Map名为counts的常量
 * 3. 循环strings数组
 * 4. 将str作为键，将str存在的次数作为值
 * @param strings String[]
 * @returns {Map<any, any>}
 * @constructor
 */
function Counter(strings = []) {
    const counts = new Map();

    for (const str of strings) {
        counts.set(
            str, // 键
            (
                counts.get(str) || 0 // 从counts中获取str的值（存在的次数），如果不存在，默认为0
            ) + 1 // 值
        );
    }

    return counts;
}

/**
 * 1. 保证缓存的利用率
 * 2. 控制缓存容量
 */
class LRUCache {
    constructor(capacity) {
        this.cache = new Map();
        this.capacity = capacity; // 最大容量
    }

    get(key) {
        if (!this.cache.has(key))
            return -1;

        const value = this.cache.get(key);
        this.cache.delete(key);
        this.cache.set(key, value); // 常用的键值对会集中在Map的底部，不常用的键值对会集中在Map的顶部

        return value;
    }

    put(key, value) {
        if (this.cache.has(key)) {
            this.cache.delete(key);
        } else if (this.cache.size >= this.capacity) {
            this.cache.delete(
                this.cache.keys().next().value // 第一个键
            );
        }
        this.cache.set(key, value);
    }
}

// Set
// 1. 去重数组：从一个可能包含重复元素的数组中去除重复值。
// 2. 集合操作：模拟数学中的集合操作，比如并集、交集、差集等。
function Duplication(arr) {
    // 类数组结构体：{ 索引:值, length: 1 }

    return Array.from( // 将类数组结构体，转换成数组
        new Set(arr)
    );
}

/**
 * 求两个集合的交集
 * @param setA
 * @param setB
 * @returns {Set<*>}
 */
function inter(setA, setB) {
    // new Set([...a, ...b]) 并集

    let array = [...setA];
    // 判断集合A中的元素，在集合B中是否存在
    // 如果存在，就保留
    // 如果不存在，就舍弃
    let filter = array.filter(x => setB.has(x));

    return new Set(filter);
}